package com.strongbj.iot.devices.reader.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.GlobalEventExecutor;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

import com.strongbj.core.message.IMessageHandleFactory;
import com.strongbj.iot.devices.reader.message.ReaderMessageHandleFactory;

public class ReaderServer implements ApplicationListener<ApplicationEvent> {
	public static final ChannelGroup channels = new DefaultChannelGroup("ReaderChannelGroup",GlobalEventExecutor.INSTANCE);
	private static Logger logger = LogManager.getLogger(ReaderServer.class.getName());

	/**
	 * Reader设备端口号
	 */
	private int port;
	
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		new Thread(new Runnable(){

			@Override
			public void run() {
				try {
					ReaderServer.bind(ReaderServer.this.port);
				} catch (Exception e) {
					e.printStackTrace();
					logger.error("#reader ReaderServer异常:"+e.getMessage());
				}
			}
		}).start();
	}
	
	// 绑定指定端口
	private static void bind(int port) throws Exception {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap serverBootstrap = new ServerBootstrap();
			serverBootstrap.group(bossGroup, workerGroup);
			serverBootstrap.channel(NioServerSocketChannel.class);
			serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024);
			serverBootstrap.handler(new LoggingHandler());
			serverBootstrap.childHandler(new NettyChannelHandler());
			serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
			ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
			System.out.println("=======ReaderServer[port:"+port+"]服务已启动=======");
			channelFuture.channel().closeFuture().sync();
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}

	private static class NettyChannelHandler extends ChannelInitializer<SocketChannel> {

		@Override
		protected void initChannel(SocketChannel socketChannel) throws Exception {
			IMessageHandleFactory factory = new ReaderMessageHandleFactory();
			socketChannel.pipeline()
					.addLast(factory.createMessageDecoder());
			socketChannel.pipeline().addLast(factory.createMessageHandle());
			logger.info("-----------Reader设备已连接[ip:"+socketChannel.remoteAddress().getAddress().getHostAddress()+":"+socketChannel.remoteAddress().getPort()+"]-----------");
		}
	}

	
	public int getPort() {
		return port;
	}

	
	public void setPort(int port) {
		this.port = port;
	}
	
}
